// WorkflowManager = {}

// WorkflowManager.getPositionsFilterByUsers = function (spaceId, orgId, roleId) {
// 	if (!spaceId || !orgId || !roleId)
// 		return []

// 	return db.flow_positions.find({
// 		space: spaceId,
// 		role: roleId,
// 		org: orgId
// 	}, {
// 		fields: {
// 			users: 1
// 		}
// 	}).fetch();
// }

// WorkflowManager.uniqUsers = function (users) {
// 	if (_.isEmpty(users))
// 		return []

// 	var users_str = [],
// 		users_obj = [];
// 	_.each(users, function (u) {
// 		users_str.push(JSON.stringify(u))
// 	})

// 	users_str = _.uniq(users_str);

// 	_.each(users_str, function (us) {
// 		users_obj.push(JSON.parse(us))
// 	})

// 	return users_obj
// }

// /*
//  返回指定部门下的角色成员,如果指定部门没有找到对应的角色，则会继续找部门的上级部门直到找到为止。
//  return [{spaceUser}]
//  */
// WorkflowManager.getRoleUsersbyOrgAndRole = function (spaceId, orgId, roleId) {
// 	var roleUsers = new Array();

// 	var orgPositions = WorkflowManager.getPositionsFilterByUsers(spaceId, orgId, roleId);

// 	orgPositions.forEach(function (orgPosition) {
// 		var roleUserIds = orgPosition.users;
// 		roleUsers = roleUsers.concat(WorkflowManager.getUsers(spaceId, roleUserIds, true));
// 	});

// 	if (orgPositions.length == 0) {
// 		var organization = WorkflowManager.getOrganization(orgId);
// 		if (organization && organization.parent != '')
// 			roleUsers = roleUsers.concat(WorkflowManager.getRoleUsersbyOrgAndRole(spaceId, organization.parent, roleId));
// 	}

// 	return roleUsers;
// };

// WorkflowManager.getRoleUsersByOrgAndRoles = function (spaceId, orgId, roleIds) {

// 	var roleUsers = new Array();

// 	roleIds.forEach(function (roleId) {
// 		roleUsers = roleUsers.concat(WorkflowManager.getRoleUsersbyOrgAndRole(spaceId, orgId, roleId));
// 	});

// 	return roleUsers;

// };

// WorkflowManager.getRoleUsersByOrgsAndRoles = function (spaceId, orgIds, roleIds) {
// 	var roleUsers = new Array();

// 	if (!orgIds || !roleIds)
// 		return roleUsers;

// 	orgIds.forEach(function (orgId) {
// 		roleUsers = roleUsers.concat(WorkflowManager.getRoleUsersByOrgAndRoles(spaceId, orgId, roleIds));
// 	});

// 	return roleUsers;
// };

// /*
//  返回用户所在部门下的角色成员.
//  return [{spaceUser}]
//  */
// WorkflowManager.getRoleUsersByUsersAndRoles = function (spaceId, userIds, roleIds) {

// 	var roleUsers = new Array();

// 	if (!userIds || !roleIds)
// 		return roleUsers;

// 	var users = WorkflowManager.getUsers(spaceId, userIds, true);

// 	users.forEach(function (user) {
// 		roleUsers = roleUsers.concat(WorkflowManager.getRoleUsersByOrgsAndRoles(spaceId, user.organizations, roleIds));
// 	});

// 	return roleUsers;
// };

// WorkflowManager.getSpaceRoles = function (spaceId) {
// 	if (!spaceId) {
// 		return;
// 	}

// 	return db.flow_roles.find({
// 		space: spaceId
// 	}).fetch();
// };

// WorkflowManager.getRole = function (spaceId, roleId) {

// 	if (!roleId || !spaceId) {
// 		return;
// 	}

// 	return db.flow_roles.findOne({
// 		_id: roleId,
// 		space: spaceId
// 	});
// };

// WorkflowManager.getSpacePositions = function (spaceId) {
// 	return db.flow_positions.find({
// 		space: spaceId
// 	}).fetch();
// };

// //获取用户岗位
// WorkflowManager.getUserRoles = function (spaceId, orgId, userId) {

// 	var userRoles = new Array();

// 	// var spacePositions = WorkflowManager.getSpacePositions(spaceId);

// 	//orgRoles = spacePositions.filterProperty("org", orgId); ？？？
// 	// var userPositions = spacePositions.filterProperty("users", userId);

// 	var userPositions = db.flow_positions.find({
// 		space: spaceId,
// 		users: userId
// 	}, {
// 		fields: {
// 			role: 1
// 		}
// 	});

// 	userPositions.forEach(function (userPosition) {
// 		userRoles.push(WorkflowManager.getRole(spaceId, userPosition.role));
// 	});

// 	return userRoles;
// };

// WorkflowManager.getOrganizationsUsers = function (spaceId, orgs) {

// 	var orgUsers = new Array();

// 	orgs.forEach(function (org) {
// 		orgUsers = orgUsers.concat(WorkflowManager.getUsers(spaceId, org.users, true));
// 	});

// 	return orgUsers;
// }

// //获取space下的所有部门
// WorkflowManager.getSpaceOrganizations = function (spaceId) {
// 	return db.organizations.find({
// 		space: spaceId
// 	}).fetch();
// };

// WorkflowManager.getOrganizationChildrens = function (spaceId, orgId) {
// 	return db.organizations.find({
// 		space: spaceId,
// 		parents: orgId
// 	}).fetch();
// };

// WorkflowManager.getOrganizationsChildrens = function (spaceId, orgIds) {
// 	var chidrenOrgs = new Array();
// 	orgIds.forEach(function (orgId) {
// 		chidrenOrgs = chidrenOrgs.concat(WorkflowManager.getOrganizationChildrens(spaceId, orgId));
// 	});

// 	return chidrenOrgs;
// };

// WorkflowManager.getOrganization = function (orgId) {
// 	if (!orgId) {
// 		return;
// 	}

// 	return db.organizations.findOne(orgId, {fields: {created: 0, created_by: 0, modified: 0, modified_by: 0}});
// };

// WorkflowManager.getOrganizations = function (orgIds) {
// 	if (!orgIds) {
// 		return [];
// 	}

// 	if ("string" == typeof (orgIds)) {
// 		return [WorkflowManager.getOrganization(orgIds)]
// 	}

// 	return db.organizations.find({
// 		_id: {
// 			$in: orgIds
// 		}
// 	}, {fields: {created: 0, created_by: 0, modified: 0, modified_by: 0}}).fetch();
// };

// WorkflowManager.getCompany = function (companyId) {
// 	if (!companyId) {
// 		return {};
// 	}
// 	return Creator.getCollection("company").findOne(companyId, {fields: {created: 0, created_by: 0, modified: 0, modified_by: 0}}) || {};
// }

// WorkflowManager.getCompanys = function (companyIds) {
// 	if (!companyIds) {
// 		return [];
// 	}

// 	if ("string" == typeof (companyIds)) {
// 		return [WorkflowManager.getCompany(companyIds)]
// 	}
// 	return Creator.getCollection("company").find({
// 		_id: {
// 			$in: companyIds
// 		}
// 	}, {fields: {created: 0, created_by: 0, modified: 0, modified_by: 0}}).fetch();
// };


// WorkflowManager.getUser = function (spaceId, userId, notNeedDetails) {
// 	if (!userId || !spaceId) {
// 		return;
// 	}

// 	if (typeof userId != "string") {
// 		return WorkflowManager.getUsers(spaceId, userId);
// 	}

// 	var spaceUser = db.space_users.findOne({
// 		space: spaceId,
// 		user: userId
// 	}, {fields: {created: 0, created_by: 0, modified: 0, modified_by: 0}});

// 	if (!spaceUser) {
// 		return
// 	}

// 	if (notNeedDetails == true) {
// 		spaceUser.id = spaceUser.user;
// 	} else {
// 		spaceUser.id = spaceUser.user;
// 		spaceUser.organization = WorkflowManager.getOrganization(spaceUser.organization);
// 		if (!spaceUser.organization) {
// 			return;
// 		}

// 		spaceUser.company = WorkflowManager.getCompany(spaceUser.company_id);
// 		spaceUser.companys = WorkflowManager.getCompanys(spaceUser.company_ids);

// 		spaceUser.roles = WorkflowManager.getUserRoles(spaceId, spaceUser.organization.id, spaceUser.id);
// 	}

// 	return spaceUser;
// };

// WorkflowManager.getUsers = function (spaceId, userIds, notNeedDetails) {

// 	if ("string" == typeof (userIds)) {
// 		return [WorkflowManager.getUser(spaceId, userIds, notNeedDetails)]
// 	}

// 	var users = new Array();
// 	if (userIds && spaceId) {
// 		var spaceUsers = db.space_users.find({
// 			space: spaceId,
// 			user: {
// 				$in: userIds
// 			}
// 		}, {fields: {created: 0, created_by: 0, modified: 0, modified_by: 0}});

// 		if (notNeedDetails == true) {
// 			spaceUsers.forEach(function (spaceUser) {
// 				spaceUser.id = spaceUser.user;
// 				users.push(spaceUser);
// 			})
// 		} else {
// 			spaceUsers.forEach(function (spaceUser) {
// 				spaceUser.id = spaceUser.user;

// 				spaceUser.organization = WorkflowManager.getOrganization(spaceUser.organization);

// 				spaceUser.organizations = WorkflowManager.getOrganizations(spaceUser.organizations);

// 				spaceUser.company = WorkflowManager.getCompany(spaceUser.company_id);
// 				spaceUser.companys = WorkflowManager.getCompanys(spaceUser.company_ids);

// 				if (spaceUser.organization) {
// 					spaceUser.roles = WorkflowManager.getUserRoles(spaceId, spaceUser.organization.id, spaceUser.id);
// 					users.push(spaceUser);
// 				}
// 			})
// 		}

// 	}

// 	return users;
// };

// WorkflowManager.getHrRolesUsers = function(spaceId, hrRoleIds){
// 	var hrRolesUsers = [];

// 	if(!_.isArray(hrRoleIds)){
// 		return [];
// 	}
// 	var hrRoles = db.roles.find({space: spaceId, _id: {$in: hrRoleIds}}).fetch();
// 	_.each(hrRoles, function(hrRole){
// 		hrRolesUsers = hrRolesUsers.concat(hrRole.users || [])
// 	});

// 	var spaceUsers = db.space_users.find({
// 		space: spaceId,
// 		user: {$in: hrRolesUsers}
// 	}, {fields: {created: 0, created_by: 0, modified: 0, modified_by: 0}}).fetch();

// 	_.each(spaceUsers, function(spaceUser){
// 		spaceUser.id = spaceUser.user
// 	});
// 	return spaceUsers
// }

// WorkflowManager.getFormulaUsers = function (spaceId, userIds) {

// 	var users = WorkflowManager.getUsers(spaceId, userIds);
// 	users.forEach(function (user) {

// 		user.organization.id = user.organization._id;

// 		user.organizations = {
// 			'id': user.organizations.getProperty("_id"),
// 			'name': user.organizations.getProperty("name"),
// 			'fullname': user.organizations.getProperty("fullname")
// 		}

// 		user.company.id = user.company._id;

// 		user.companys = {
// 			'id': user.companys.getProperty("_id"),
// 			'name': user.companys.getProperty("name"),
// 			'code': user.companys.getProperty("code"),
// 		}

// 		if (!user.hr) {
// 			user.hr = {}
// 		}

// 		user.roles = user.roles ? user.roles.getProperty('name') : [];
// 	})

// 	return users;
// }

// WorkflowManager.getFormulaUserObjects = function (spaceId, userIds) {
// 	if (!userIds)
// 		return {
// 			organization: {},
// 			hr: {}
// 		};
// 	return WorkflowManager.getFormulaUserObject(spaceId, userIds);
// }

// WorkflowManager.getFormulaUserObject = function (spaceId, userId) {

// 	if (!userId)
// 		return {
// 			organization: {},
// 			hr: {}
// 		};

// 	if (userId instanceof Array) {
// 		return WorkflowManager.getFormulaUsers(spaceId, userId);
// 	} else {
// 		return WorkflowManager.getFormulaUsers(spaceId, [userId])[0];
// 	}
// };


// WorkflowManager.getFormulaOrgObjects = function (orgIds) {
// 	if (!orgIds)
// 		return;
// 	return WorkflowManager.getFormulaOrgObject(orgIds);
// }

// WorkflowManager.getFormulaOrgObject = function (orgId) {

// 	if (orgId instanceof Array) {
// 		var orgs = WorkflowManager.getOrganizations(orgId);
// 		orgs.forEach(function (org) {
// 			org.id = org._id;
// 		});

// 		return orgs;
// 	} else {
// 		var org = WorkflowManager.getOrganization(orgId);
// 		if (!org)
// 			return null;

// 		org.id = orgId;

// 		return org;
// 	}

// }

// WorkflowManager.getInstanceFormVersion = function () {

// 	var instance = Template.instance().view.template.steedosData.instance

// 	var form, form_fields, form_version;
// 	form = db.forms.findOne(instance.form);
// 	form_version = {};
// 	form_fields = [];
// 	if (form.current._id === instance.form_version) {
// 		form_version = form.current;
// 	} else {
// 		form_version = _.where(form.historys, {
// 			_id: instance.form_version
// 		})[0];
// 	}
// 	form_version.fields.forEach(function (field) {
// 		if (field.type === 'section') {
// 			form_fields.push(field);
// 			if (field.fields) {
// 				return field.fields.forEach(function (f) {
// 					return form_fields.push(f);
// 				});
// 			}
// 		} else if (field.type === 'table') {
// 			field['sfields'] = field['fields'];
// 			delete field['fields'];
// 			return form_fields.push(field);
// 		} else {
// 			return form_fields.push(field);
// 		}
// 	});
// 	form_version.fields = form_fields;
// 	return form_version;
// };

// WorkflowManager.getFormVersion = function (id, versionId) {
// 	var form = db.forms.findOne({
// 		_id: id
// 	});

// 	var form_version = form.current

// 	if (form_version._id != versionId) {
// 		form_version = form.historys.findPropertyByPK("_id", versionId)
// 	}

// 	var form_fields = [];

// 	form_version.fields.forEach(function (field) {
// 		if (field.type == 'section') {
// 			form_fields.push(field);
// 			if (field.fields) {
// 				field.fields.forEach(function (f) {
// 					form_fields.push(f);
// 				});
// 			}
// 		} else {
// 			form_fields.push(field);
// 		}
// 	});

// 	form_version.fields = form_fields;

// 	return form_version;
// }

// WorkflowManager.getInstanceFlowVersion = function (instance) {
// 	if (!instance) {
// 		instance = Template.instance().view.template.steedosData.instance;
// 	}

// 	var flow, flow_version;
// 	flow = db.flows.findOne(instance.flow);
// 	flow_version = {};
// 	if (flow.current._id === instance.flow_version) {
// 		flow_version = flow.current;
// 	} else {
// 		flow_version = _.where(flow.historys, {
// 			_id: instance.flow_version
// 		})[0];
// 	}
// 	return flow_version;
// };

// WorkflowManager.getInstanceStep = function (stepId) {
// 	flow = WorkflowManager.getInstanceFlowVersion();

// 	if (!flow)
// 		return null;

// 	var g_step;

// 	flow.steps.forEach(
// 		function (step) {
// 			if (step._id == stepId) {
// 				g_step = step;
// 				g_step.id = step._id;
// 				return;
// 			}
// 		}
// 	);

// 	return g_step;
// };


// WorkflowManager.canAdmin = function (fl, curSpaceUser, organizations) {
// 	var perms = fl.perms;
// 	var hasAdminRight = false;
// 	if (perms) {
// 		if (perms.users_can_admin && perms.users_can_admin.includes(curSpaceUser.user)) {
// 			hasAdminRight = true;
// 		} else if (perms.orgs_can_admin && perms.orgs_can_admin.length > 0) {
// 			if (curSpaceUser && curSpaceUser.organizations && _.intersection(curSpaceUser.organizations, perms.orgs_can_admin).length > 0) {
// 				hasAdminRight = true;
// 			} else {
// 				if (organizations) {

// 					hasAdminRight = _.some(organizations, function (org) {
// 						return org.parents && _.intersection(org.parents, perms.orgs_can_admin).length > 0;
// 					});
// 				}
// 			}
// 		}
// 	}
// 	return hasAdminRight;
// };

// WorkflowManager.canMonitor = function (fl, curSpaceUser, organizations) {
// 	var perms = fl.perms;
// 	var hasMonitorRight = false;
// 	if (perms) {
// 		if (perms.users_can_monitor && perms.users_can_monitor.includes(curSpaceUser.user)) {
// 			hasMonitorRight = true;
// 		} else if (perms.orgs_can_monitor && perms.orgs_can_monitor.length > 0) {
// 			if (curSpaceUser && curSpaceUser.organizations && _.intersection(curSpaceUser.organizations, perms.orgs_can_monitor).length > 0) {
// 				hasMonitorRight = true;
// 			} else {
// 				if (organizations) {

// 					hasMonitorRight = _.some(organizations, function (org) {
// 						return org.parents && _.intersection(org.parents, perms.orgs_can_monitor).length > 0;
// 					});
// 				}
// 			}
// 		}
// 	}
// 	return hasMonitorRight;
// };

// //校验user是否对instance有查看权限：
// // 1 工作区管理员则返回true
// // 2 用户在submitter、applicant、outbox_users、inbox_users、cc_users、created_by、modified_by 中：return true;
// // 3 用户是流程管理员，监控员：return true;
// // 4 否则：return false;
// WorkflowManager.hasInstancePermissions = function (user, instance) {

// 	if (user && instance) {
// 		var space = db.spaces.findOne({
// 			_id: instance.space
// 		}, {
// 			fields: {
// 				admins: 1
// 			}
// 		});
// 		if (space && space.admins && space.admins.includes(user._id)) {
// 			return true;
// 		}
// 	}

// 	var approvedUsers = _.union(instance.outbox_users, instance.inbox_users, instance.cc_users, [instance.submitter], [instance.applicant], [instance.created_by], [instance.modified_by]);

// 	if (approvedUsers.includes(user._id)) {
// 		return true;
// 	}

// 	//被那些instance关联
// 	var originalInstances = db.instances.find({
// 		related_instances: {
// 			$all: [instance._id]
// 		}
// 	}, {
// 		fields: {
// 			outbox_users: 1,
// 			inbox_users: 1,
// 			cc_users: 1,
// 			submitter: 1,
// 			applicant: 1
// 		}
// 	})
// 	console.log("originalInstances size is " + originalInstances.count());
// 	if (originalInstances.count() > 0) {
// 		var hasPermission = false;
// 		_.some(originalInstances.fetch(), function (ins) {
// 			console.log(ins)
// 			havePermissionUsers = _.union(ins.outbox_users, ins.inbox_users, ins.cc_users, [ins.submitter], [ins.applicant]);
// 			console.log(havePermissionUsers)
// 			if (havePermissionUsers.includes(user._id)) {
// 				hasPermission = true;
// 				return true;
// 			}
// 		})
// 		if (hasPermission) {
// 			return true;
// 		}
// 	}

// 	spaceUser = db.space_users.findOne({
// 		space: instance.space,
// 		user: user._id
// 	})

// 	if (spaceUser) {
// 		organizations = db.organizations.find({
// 			_id: {
// 				$in: spaceUser.organizations
// 			}
// 		}).fetch();

// 		flow = db.flows.findOne({
// 			_id: instance.flow
// 		});

// 		if (flow) {
// 			return WorkflowManager.canMonitor(flow, spaceUser, organizations) || WorkflowManager.canAdmin(flow, spaceUser, organizations)
// 		}
// 		return false;
// 	}
// 	return false;

// }

// WorkflowManager.getNameForUser = function (userId) {
// 	check(userId, String);
// 	return db.users.findOne({
// 		_id: userId
// 	}, {
// 		fields: {
// 			name: 1
// 		}
// 	});
// }

// // 工作区管理员和流程管理员拥有流程的管理权限
// WorkflowManager.hasFlowAdminPermission = function (flow_id, space_id, user_id) {
// 	var space = db.spaces.findOne({
// 		_id: space_id
// 	}, {
// 		fields: {
// 			admins: 1
// 		}
// 	});

// 	if (!space)
// 		return false;

// 	if (space.admins && space.admins.includes(user_id))
// 		return true;

// 	var hasPermission = false;

// 	var space_user = db.space_users.findOne({
// 		space: space_id,
// 		user: user_id
// 	}, {
// 		fields: {
// 			organizations: 1,
// 			user: 1
// 		}
// 	})
// 	if (space_user) {
// 		var organizations = db.organizations.find({
// 			_id: {
// 				$in: space_user.organizations
// 			}
// 		}, {
// 			fields: {
// 				parents: 1
// 			}
// 		}).fetch()

// 		var fl = db.flows.findOne({
// 			_id: flow_id
// 		}, {
// 			fields: {
// 				perms: 1
// 			}
// 		})

// 		if (fl && organizations) {
// 			hasPermission = WorkflowManager.canAdmin(fl, space_user, organizations);
// 		}
// 	}

// 	return hasPermission;

// }

// WorkflowManager.getMyAdminOrMonitorFlows = function(spaceId, userId) {
// 	var flows, flow_ids = [],
// 		curSpaceUser, organization;
// 	curSpaceUser = db.space_users.findOne({
// 		space: spaceId,
// 		'user': userId
// 	});
// 	if (curSpaceUser) {
// 		organizations = db.organizations.find({
// 			_id: {
// 				$in: curSpaceUser.organizations
// 			}
// 		}).fetch();
// 		flows = db.flows.find();
// 		flows.forEach(function(fl) {
// 			if (WorkflowManager.canMonitor(fl, curSpaceUser, organizations) || WorkflowManager.canAdmin(fl, curSpaceUser, organizations)) {
// 				flow_ids.push(fl._id);
// 			}
// 		})
// 	}
// 	return flow_ids;
// };